/*
 * Copyright 2006 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.client.ui;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Abstract base class for panels that contain only one widget.
 */
public abstract class SimplePanel extends Panel {

  private Widget widget;

  /**
   * Creates an empty panel that uses a DIV for its contents.
   */
  protected SimplePanel() {
    this(DOM.createDiv());
  }

  /**
   * Creates an empty panel that uses the specified browser element for its
   * contents.
   * 
   * @param handle a handle to the browser element to use
   */
  protected SimplePanel(Element elem) {
    setElement(elem);
  }

  public boolean add(Widget w) {
    if (widget != null)
      return false;

    DOM.appendChild(getContainerElement(), w.getElement());
    setWidget(w);
    return true;
  }
  
  public void clear() {
    if(widget != null) {
      remove(widget);
    }
  }

  public Widget getWidget(int index) {
    if (index == 0)
      return widget;
    return null;
  }

  public int getWidgetCount() {
    return (widget != null) ? 1 : 0;
  }

  public int getWidgetIndex(Widget child) {
    if (child == widget)
      return 0;
    return -1;
  }

  public Iterator iterator() {
    // Return a simple iterator that enumerates the 0 or 1 elements in this
    // panel.
    return new Iterator() {
      boolean hasElement = widget != null;

      public boolean hasNext() {
        return hasElement;
      }

      public Object next() {
        if (!hasElement || (widget == null))
          throw new NoSuchElementException();
        hasElement = false;
        return widget;
      }

      public void remove() {
        throw new UnsupportedOperationException();
      }
    };
  }

  public boolean remove(Widget w) {
    if (widget == w) {
      widget = w;
      DOM.removeChild(getContainerElement(), w.getElement());
      w.setParent(null);
      return true;
    }
    return false;
  }

  /**
   * Override this method to specify that an element other than the root element
   * be the container for the panel's child widget. This can be useful when you
   * want to create a simple panel that decorates its contents.
   * 
   * @return the element to be used as the panel's container
   */
  protected Element getContainerElement() {
    return getElement();
  }

  protected void setWidget(Widget w) {
    widget = w;
    w.setParent(this);
  }
}
